﻿#region Using

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Dictionary.Tools;

#endregion

namespace Dictionary {
    public partial class ModifyWordForm : Form {
        #region Properties

        public string Type { get; set; }
        public List<string> OldWords { get; set; }
        public bool IsSaved { get; set; }
        public MainForm MainForm { get; set; }

        #endregion

        public ModifyWordForm() {
            InitializeComponent();
        }

        /// <summary>
        /// ModifyWordForm is created to update words
        /// </summary>
        /// <param name="commonValue"></param>
        /// <param name="words"></param>
        /// <param name="type">Change or Add</param>
        /// <param name="mainForm">Reference of MainForm owner</param>
        public ModifyWordForm(string commonValue, List<string> words, string type, MainForm mainForm) {
            MainForm = mainForm;
            IsSaved = true;
            Type = type;
            InitializeComponent();
            if (Type != "Change") return;
            // Insert Word definition
            InsertWordDef(words[0], ref rEngSpec, ref textBox1);
            InsertWordDef(words[1], ref rRusSpec, ref textBox2);
            InsertWordDef(words[2], ref rViSpec, ref textBox3);
            // Copy the old words, used for updating later
            OldWords = words;
            // Insert commonValue
            rEngComm.Text = rViComm.Text = rRusComm.Text = commonValue;
            // Set all textbox to Readonly
        }

        public void InsertWordDef(string word, ref RichTextBox rtb, ref TextBox textBox) {
            if (word == null) return;
            textBox.Text = word;
            string value = Controller.Controller.GetValueOf(word);
            rtb.Text = value.Replace('|', '\n');
        }

        #region Menu insert characters

        // Helper: Get all controls recursive
        public bool IsFocusedRtb(Control control) {
            if (control.GetType() != typeof (RichTextBox)) return false;
            var rtb = (RichTextBox) control;
            return rtb.Focused;
        }

        // Helper: Find focused richtextBox
        private Control GetFocusedRtb(Control.ControlCollection controlCollection) {
            foreach (Control control in controlCollection) {
                if (IsFocusedRtb(control))
                    return control;
                if (control.Controls.Count <= 0) continue;
                Control result = GetFocusedRtb(control.Controls);
                if (result != null)
                    return result;
            }
            return null;
        }

        private void ToolStripMenuItemClick(object sender, EventArgs e) {
            var rtb = (RichTextBox) GetFocusedRtb(Controls);
            var toolStrip = (ToolStripMenuItem) sender;
            if (rtb != null) {
                rtb.Text += Environment.NewLine + toolStrip.Tag;
                rtb.SelectionStart = rtb.Text.Length;
            }
        }

        #endregion

        #region Events

        private void REngTextChanged(object sender, EventArgs e) {
            IsSaved = false;
            string text = rEngSpec.Text + '\n' + rEngComm.Text;
            text = text.Replace('\n', '|');
            ParseHelper.ParseValue(text, ref rEngReview);
        }

        private void RRusTextChanged(object sender, EventArgs e) {
            IsSaved = false;
            string text = rRusSpec.Text + '\n' + rRusComm.Text;
            text = text.Replace('\n', '|');
            ParseHelper.ParseValue(text, ref rRusReview);
        }

        private void RViTextChanged(object sender, EventArgs e) {
            IsSaved = false;
            string text = rViSpec.Text + '\n' + rViComm.Text;
            text = text.Replace('\n', '|');
            ParseHelper.ParseValue(text, ref rViReview);
        }

        // CommonValue changed
        private void CommonValueChanged(object sender, EventArgs e) {
            IsSaved = false;
            var rtb = (RichTextBox) sender;
            rEngComm.Text = rRusComm.Text = rViComm.Text = rtb.Text;
            rEngComm.SelectionStart = rRusComm.SelectionStart = rViComm.SelectionStart = rtb.Text.Length;
            switch (rtb.Name) {
                case "rEngComm":
                    REngTextChanged(null, null);
                    break;
                case "rRusComm":
                    RRusTextChanged(null, null);
                    break;
                case "rViComm":
                    RViTextChanged(null, null);
                    break;
            }
        }

        // Helper: Save changed
        private bool IsDuplicate(string word) {
            if (MainForm.Words.Find(str => str == word) != null) {
                MessageBox.Show("Bạn đã nhập từ có trong từ điển, hãy nhập lại", "Trùng", MessageBoxButtons.OK);
                IsSaved = true;
                return true;
            }
            return false;
        }

        private bool UpdateValues() {
            // Get commonvalueId of exist words

            int commonValueId = Controller.Controller.GetCommonValueId(OldWords.Find(s => s != ""));
            string commonValue = rEngComm.Text.Trim().Replace('\n', '|');


            {
                // Eng
                string engValue = rEngSpec.Text.Trim().Replace('\n', '|');
                if (OldWords[0] == "" && textBox1.Text != "") {
                    if (IsDuplicate(textBox1.Text)) return false;
                    Controller.Controller.InsertWord(textBox1.Text, null, commonValueId, engValue, 1);
                    MainForm.AddWordToList(textBox1.Text);
                }
                else if (OldWords[0] != "" && textBox1.Text != "" && OldWords[0] != textBox1.Text) {
                    if (IsDuplicate(textBox1.Text)) return false;
                    Controller.Controller.UpdateValue(OldWords[0], textBox1.Text, engValue, commonValue);
                    MainForm.ChangeWordInList(OldWords[0], textBox1.Text);
                }
                OldWords[0] = textBox1.Text;
            }
            {
                // Rus 
                string rusValue = rRusSpec.Text.Trim().Replace('\n', '|');
                if (OldWords[1] == "" && textBox2.Text != "") {
                    if (IsDuplicate(textBox2.Text)) return false;
                    Controller.Controller.InsertWord(textBox2.Text, null, commonValueId, rusValue, 2);
                    MainForm.AddWordToList(textBox2.Text);
                }
                else if (OldWords[1] != "" && textBox2.Text != "" && OldWords[1] != textBox2.Text) {
                    if (IsDuplicate(textBox2.Text)) return false;
                    Controller.Controller.UpdateValue(OldWords[1], textBox2.Text, rusValue, commonValue);
                    MainForm.ChangeWordInList(OldWords[1], textBox2.Text);
                }
                OldWords[1] = textBox2.Text;
            }
            {
                // Vi 
                string viValue = rViSpec.Text.Trim().Replace('\n', '|');
                if (OldWords[2] == "" && textBox3.Text != "") {
                    if (IsDuplicate(textBox3.Text)) return false;
                    Controller.Controller.InsertWord(textBox3.Text, null, commonValueId, viValue, 3);
                    MainForm.AddWordToList(textBox3.Text);
                }
                else if (OldWords[2] != "" && textBox3.Text != "" && OldWords[2] != textBox3.Text) {
                    if (IsDuplicate(textBox3.Text)) return false;
                    Controller.Controller.UpdateValue(OldWords[2], textBox3.Text, viValue, commonValue);
                    MainForm.ChangeWordInList(OldWords[2], textBox3.Text);
                }
                OldWords[2] = textBox3.Text;
            }
            return true;
        }

        // Helper: Insert values
        private bool InsertValues() {
            string engWord = textBox1.Text.Trim();
            string rusWord = textBox2.Text.Trim();
            string viWord = textBox3.Text.Trim();

            if (engWord == rusWord || rusWord == viWord || viWord == engWord) {
                MessageBox.Show("Bạn đã nhập từ có trong từ điển, hãy nhập lại", "Trùng", MessageBoxButtons.OK);
                return false;
            }


            string engValue = rEngSpec.Text.Trim().Replace('\n', '|');
            string rusValue = rRusSpec.Text.Trim().Replace('\n', '|');
            string viValue = rViSpec.Text.Trim().Replace('\n', '|');
            string commonValue = rEngComm.Text.Trim().Replace('\n', '|');

            // We get 1 commonvalueId once for insert later
            // Get commonValueId once and use later instead of commonValue
            int comValueId = Controller.Controller.InsertWord(engWord, commonValue, 0, engValue, 1);
            Controller.Controller.InsertWord(rusWord, null, comValueId, rusValue, 2);
            Controller.Controller.InsertWord(viWord, null, comValueId, viValue, 3);

            // Insert new values to list
            MainForm.AddWordToList(engWord);
            MainForm.AddWordToList(rusWord);
            MainForm.AddWordToList(viWord);

            return true;
        }

        private void AddWordFormFormClosed(object sender, FormClosedEventArgs e) {
            // Ask for saving
            if (IsSaved == false) {
                switch (
                    MessageBox.Show(@"Bạn muốn thực hiện những thay đổi đã thực hiện không ?", @"Lưu thay đổi",
                                    MessageBoxButtons.OKCancel)) {
                                        case DialogResult.OK:
                                            if (Type == "Change")
                                                UpdateValues();
                                            else
                                                InsertValues();
                                            MessageBox.Show(@"Thành công!", @"Lưu thay đổi đã thực hiện",
                                                            MessageBoxButtons.OK);
                                            break;
                }
            }
        }

        private void SaveClicked(object sender, EventArgs e) {
            bool result = false;
            if (Type == "Change")
                result = UpdateValues();
            else
                result = InsertValues();
            if (result) MessageBox.Show(@"Thành công!", @"Lưu thay đổi đã thực hiện", MessageBoxButtons.OK);
            IsSaved = true;
        }

        #endregion
    }
}